<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="renderer" content="webkit|ie-comp|ie-stand">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <title>每日统计</title>
</head>

<body>
  <div id="app" v-loading.fullscreen.lock="loading">
    <div class="per-day-stat">
      <div>
        <search-btn-view btn-text="统计查询" :before-search="checkSearchValid" @before-open="resetSearch" @search="searchData">
          <div slot="search-content">
            <search-form :search="search" :person-list="personList"></search-form>
          </div>
        </search-btn-view>
      </div>
      <div class="day-stat-table-div" :class="{'hasPage':pagination.totalCount!==0}">
        <el-table fit stripe border class="day-stat-table" :data="statList" style="width: 100%" height="parent">
          <el-table-column :resizable="false" label="姓名" prop="userName" key="userName" min-width="100px" align="center"
            fixed="left"></el-table-column>
          <el-table-column :resizable="false" label="部门" prop="deptName" key="deptName" min-width="80px" align="center"></el-table-column>
          <el-table-column :resizable="false" label="编号" prop="userId" key="userId" min-width="60px" align="center"></el-table-column>
          <el-table-column :resizable="false" label="工号" prop="workerNo" key="workerNo" min-width="60px" align="center"></el-table-column>
          <el-table-column :resizable="false" label="日期" key="workdate" min-width="135px" align="center">
            <template slot-scope="scope">
              <span>{{moment(scope.row.workdate).format('YYYY-MM-DD dddd')}}</span>
            </template>
          </el-table-column>
          <el-table-column :resizable="false" label="班次" key="classId" min-width="150px" align="center">
            <template slot-scope="scope">
              <span>{{getUserClass(scope.row)}}</span>
            </template>
          </el-table-column>

          <template v-for="(count,index) in maxCardCount">
            <el-table-column :resizable="false" :label="`${index%2===0?'上班':'下班'}${Math.floor((count+1)/2)}`" :key="`duty_${count}`"
              align="center">
              <el-table-column :resizable="false" label="打卡时间" :key="`duty_time_${count}`" align="center" min-width="80px">
                <template slot-scope="scope">
                  <span v-if="scope.row.clockList[index]&&scope.row.clockList[index].userCheckTime!==null">
                    {{moment(scope.row.clockList[index].userCheckTime).format('HH:mm')}}
                  </span>
                </template>
              </el-table-column>
              <el-table-column :resizable="false" label="打卡结果" :key="`duty_result_${count}`" align="center" min-width="100px">
                <template slot-scope="scope">
                  <span v-if="scope.row.clockList[index]" :class="`status-${scope.row.clockList[index].className}`"
                    class="attendance-result" @click="toAttendanceDetail(scope.row)">
                    {{statusList[scope.row.clockList[index].status]}}
                    <template v-if="scope.row.clockList[index].rangeTime!==null">
                      {{SysUtil.getDurationStr(scope.row.clockList[index].rangeTime)}}
                    </template>
                  </span>
                </template>
              </el-table-column>
            </el-table-column>
          </template>

          <el-table-column :resizable="false" label="关联的审批单" key="leave" min-width="150px" align="center">
            <template slot-scope="scope">
              <div class="status-abnormal" v-html="getLeaveHtml(scope.row)"></div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div style="margin-top:10px;text-align:right;" v-if="pagination.totalCount!==0">
        <el-pagination background :page-size="pagination.pageSize" :total="pagination.totalCount" :current-page.sync="pagination.currentPage"
          @current-change="pageChange"></el-pagination>
      </div>
    </div>

    <el-dialog :title="detailTitle" :visible.sync="openDetail" top="10vh" custom-class="statDetailDialog" @closed="statDetail=null"
      width="50%">
      <div style="height:calc(80vh - 54px);overflow:auto">
        <attendance-detail v-if="openDetail" :detail="statDetail" :is-format="false"></attendance-detail>
      </div>
    </el-dialog>
  </div>
</body>

<script src="../../myJs/importFile.js"></script>
<script>
  importFile([
    "/vueSystem/components/css/searchBtnView.css",
    "/vueSystem/components/css/deptTransfer.css",
    "../components/css/deptPersonSelect.css",
    "../components/css/attendanceSearchForm.css",
    "../components/css/attendanceDetail.css"
  ], [
    "/vueSystem/i18n/index.js",
    "/vueSystem/components/searchBtnView.js",
    "/vueSystem/components/deptTransfer.js",
    "/vueSystem/mixins/datePickerOptionsMixin.js"
  ]);
</script>
<script src="../utils/moduleUtil.js"></script>
<script src="../components/deptPersonSelect.js"></script>
<script src="../components/attendanceSearchForm.js"></script>
<script src="../components/attendanceDetail.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: function () {
      var search = {
        startDate: moment().startOf('month').valueOf(),
        endDate: moment().valueOf(),
        deptPerson: {
          depts: [],
          persons: []
        }
      };
      return {
        loading: false,
        search: _.cloneDeep(search),
        oldSearch: _.cloneDeep(search),
        personList: [],
        statList: [],
        maxCardCount: 0,
        statDetail: null,
        detailTitle: '',
        openDetail: false,
        pagination: {
          currentPage: 1,
          totalCount: 0,
          pageSize: 30
        },
        statusList: {
          normal: "正常",
          late: "迟到",
          early: "早退",
          lack: "缺卡",
          leave: "请假"
        },
        moment: moment,
        SysUtil: SysUtil
      };
    },

    created: function () {
      this.loading = true;
      var self = this;
      Promise.all([this.setPersonList(), this.setStatList(true)]).then(function (res) {
        self.loading = false;
      }).catch(function () {
        self.loading = false;
      });
    },

    methods: {
      setPersonList: function () {
        var self = this;
        return ajaxRequest('dingTalk/askForApprover').then(function (personList) {
          personList = _.map(personList, function (person) {
            return {
              deptId: person.deptId,
              deptName: person.deptName,
              userId: person.id,
              userName: person.personName
            };
          });
          self.personList = personList;
          return personList;
        });
      },

      setStatList: function (isSearch) {
        if (!isSearch) {
          this.search = _.cloneDeep(this.oldSearch);
        }

        var search = this.search;
        var postData = {
          startDate: moment(search.startDate).format('YYYY-MM-DD'),
          endDate: moment(search.endDate).format('YYYY-MM-DD'),
        };

        var deptPerson = search.deptPerson;
        postData.deptIds = JSON.stringify(_.map(deptPerson.depts, 'id'));
        postData.userIds = JSON.stringify(_.map(deptPerson.persons, 'id'));

        var pagination = this.pagination;
        var currentPage = pagination.currentPage;
        var pageSize = pagination.pageSize;
        var start = (currentPage - 1) * pageSize;
        postData.start = start;
        postData.length = pageSize;

        var self = this;
        return ajaxRequest('dingTalk/queryDailyStatistics', postData).then(function (res) {
          if (isSearch) {
            self.oldSearch = _.cloneDeep(self.search);
          }

          var statList = res.returnData;
          self.formatStatList(statList);

          self.statList = statList;
          self.pagination.totalCount = res.iTotalRecords;
          return statList;
        });
      },

      formatStatList: function (statList) {
        var maxCardCount = 0;
        for (var i = 0; i < statList.length; i++) {
          var stat = statList[i];
          var attendanceTime = stat.attendanceTime;
          if (attendanceTime !== null) {
            var arr = attendanceTime.split(' ');
            if (maxCardCount < arr.length) {
              maxCardCount = arr.length;
            }
          }
        }
        maxCardCount *= 2;
        this.maxCardCount = maxCardCount;

        for (var i = 0; i < statList.length; i++) {
          var stat = statList[i];

          var clockList = stat.clockList;
          clockList = clockList.splice(0, maxCardCount);
          var leaveList = stat.leaveList;
          for (var j = 0; j < clockList.length; j++) {
            var clock = clockList[j];
            var baseCheckTime = clock.baseCheckTime;
            baseCheckTime = moment(baseCheckTime).valueOf();
            clock.baseCheckTime = baseCheckTime;

            var userCheckTime = clock.userCheckTime;
            if (userCheckTime === undefined || userCheckTime === null) {
              userCheckTime = null;
            } else {
              userCheckTime = moment(userCheckTime).startOf('minute').valueOf();
            }
            clock.userCheckTime = userCheckTime;

            var status = clock.timeResult;
            var rangeTime = null;
            if (status === 'late' || status === 'early') {
              rangeTime = ModuleUtil.getAttendanceDelayTime(clock, status, leaveList);
              if (rangeTime <= 0) {
                status = 'leave';
                rangeTime = null;
              }
            } else if (status === 'lack' || status === 'normal') {
              var isLeave = this.hasLeave(clock, leaveList);
              if (isLeave) {
                status = 'leave';
              }
            }
            clock.rangeTime = rangeTime;
            clock.status = status;

            if (status === 'normal') {
              clock.className = "normal";
            } else {
              clock.className = "abnormal";
            }
          }
          stat.clockList = clockList;
        }
      },

      hasLeave: function (clock, leaveList) {
        if (leaveList.length === 0) {
          return false;
        }

        var baseCheckTime = clock.baseCheckTime;
        var leave = _.find(leaveList, function (leave) {
          var startTime = leave.startTime;
          var endTime = leave.endTime;
          return moment(baseCheckTime).isBetween(startTime, endTime, 'minute', '[]');
        });

        if (leave !== undefined) {
          leave = _.cloneDeep(leave);
          leave.startTime = moment(leave.startTime).valueOf();
          leave.endTime = moment(leave.endTime).valueOf();
          return true;
        }
        return false;
      },

      resetStatList: function (isSearch) {
        this.loading = true;
        var self = this;
        this.setStatList(isSearch).then(function () {
          self.loading = false;
        }).catch(function () {
          self.loading = false;
        });
      },

      checkSearchValid: function () {
        var search = this.search;
        var startDate = search.startDate;
        var endDate = search.endDate;
        if (moment(startDate).add(1, 'month').isBefore(endDate, 'day')) {
          this.$alert('只能查询一个月以内的汇总数据', '信息');
          return false;
        }
        return true;
      },

      resetSearch: function () {
        this.search = _.cloneDeep(this.oldSearch);
      },

      searchData: function () {
        this.pagination.currentPage = 1;
        this.resetStatList(true);
      },

      pageChange: function () {
        this.resetStatList();
      },

      getUserClass: function (stat) {
        var className = stat.className;
        if (className === null) {
          return '休息';
        }

        return `${className} ${stat.attendanceTime}`;
      },

      getLeaveHtml: function (stat) {
        var leaveList = stat.leaveList;
        var leaveHtmls = [];
        for (var i = 0; i < leaveList.length; i++) {
          var leave = leaveList[i];
          var type = leave.type;
          var startTime = leave.startTime;
          startTime = moment(startTime).format('MM-DD HH:mm');
          var endTime = leave.endTime;
          endTime = moment(endTime).format('MM-DD HH:mm');
          var str = `<div>${i18n.getMsg('attendance.takeOffType.'+leave.type)} ${startTime}到${endTime} ${leave.duration}小时</div>`;
          leaveHtmls.push(str);
        }
        return leaveHtmls.join("");
      },

      toAttendanceDetail: function (stat) {
        this.detailTitle = `${stat.userName} ${moment(stat.workdate).format('YYYY-MM-DD dddd')}`;
        this.statDetail = stat;
        this.openDetail = true;
      }
    },

    components: {
      SearchBtnView: SearchBtnView,
      SearchForm: AttendanceSearchForm,
      AttendanceDetail: AttendanceDetail
    }
  });
</script>
<style>
  .per-day-stat {
    padding: 10px 20px;
    padding-bottom: 5px;
    height: calc(100% - 15px);
  }

  .per-day-stat .day-stat-table-div {
    height: calc(100% - 46px);
    overflow: auto;
  }

  .per-day-stat .day-stat-table-div.hasPage {
    height: calc(100% - 88px);
  }

  .per-day-stat .day-stat-table .status-normal {
    color: #4B8DFA;
  }

  .per-day-stat .day-stat-table .status-abnormal {
    color: #FF9533;
  }

  .per-day-stat .day-stat-table .attendance-result {
    cursor: pointer;
  }

  .statDetailDialog .el-dialog__title {
    font-size: 14px;
  }
</style>

</html>